﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Recursos.Model;
using System.Drawing;
using System.Globalization;

namespace Recursos.View
{
    public partial class AgendaMonthView : System.Web.UI.Page
    {
        static private string[,,] mapReservaciones;
        static private Dictionary<string, int> mapHoras;
        static private Dictionary<string, int> mapDias;
        static private Dictionary<int, string> mapMTN;

        protected void Page_Load(object sender, EventArgs e)
        {
            mapHoras = new Dictionary<string, int> {{"07", 0}, {"08", 1}, {"09", 2}, {"10", 3}, {"11", 4}, 
            {"13", 5}, {"14", 6}, {"15", 7}, {"16", 8}, {"17", 9}, {"18", 10}, {"19", 11},{"20", 12}, {"21", 13}};

            mapMTN = new Dictionary<int, string> {{0, "M"}, {1, "M"}, {2, "M"}, {3, "M"}, {4, "M"}, 
            {5, "T"}, {6, "T"}, {7, "T"}, {8, "T"}, {9, "T"}, {10, "N"}, {11, "N"},{12, "N"}, {13, "N"}};

            mapDias = new Dictionary<string, int> {{"L", 0}, {"K", 1}, {"M", 2}, {"J", 3}, {"V", 4}, {"S", 5}};

            var userSecurity = ((Usuario)Session["UserLogged"]);


            if (!Page.IsPostBack && userSecurity != null)
            {
                CargarEspacios();
                DateTime elegida;
                if (Session["fechaDesp"] != null)
                    elegida = DateTime.Parse((string)Session["fechaDesp"]);
                else
                {
                    DateTime primeroMes = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                    elegida = inicioSemana(primeroMes);
                }

                Calendar1.SelectedDate = elegida;
                Calendar1.VisibleDate = elegida.AddDays(15);

                if (Session["espacioDesp"] != null)
                    DropDownEspacios.SelectedValue = (string)Session["espacioDesp"];

                DibujarMes();
            }
            else if (userSecurity == null)
            {
                Response.Redirect("~/NoAccess.aspx");
            }
        }

        private void CargarEspacios()
        {
            var espacios = new EspacioModel();
            DropDownEspacios.DataSource = espacios.CargarEspacios();
            DropDownEspacios.DataTextField = "Codigo";
            DropDownEspacios.DataValueField = "id";
            DropDownEspacios.DataBind();
        }

        private void DibujarMes()
        {
            LimpiarDespliegue();
            mapReservaciones = new string[14, 6, 5]; // 14 horas, 6 días, 5 semanas

            DateTime fechaDespliegue = Calendar1.SelectedDate.AddDays(15);
            CultureInfo espanol = new CultureInfo("es-ES");
            labelFecha.Text = fechaDespliegue.ToString("MMMMMMMMM \\de yyyy", espanol);

            setLabels();

            var model = new RservacionModel();
            var reservaciones = model.CargarReservacionesEspacioAnno(Convert.ToInt32(DropDownEspacios.SelectedValue), fechaDespliegue.Year);
            var reservacionesP = model.CargarReservacionesParticualresEspacioAnno(Convert.ToInt32(DropDownEspacios.SelectedValue), fechaDespliegue.Year);

            loopReservaciones(reservaciones);
            loopReservacionesP(reservacionesP);
        }

        protected void ClickSemana(Object sender, EventArgs e)
        {
            Session["fechaDesp"] = Calendar1.SelectedDate.ToString();
            Response.Redirect("~/View/AgendaSemanaView.aspx");
        }

        protected void ClickDia(Object sender, EventArgs e)
        {
            Session["fechaDesp"] = Calendar1.SelectedDate.ToString();
            Response.Redirect("~/View/AgendaDiaView.aspx");
        }

        protected void ClickCalendario(Object sender, EventArgs e)
        {
            DateTime primeroMes = new DateTime(Calendar1.SelectedDate.Year, Calendar1.SelectedDate.Month, 1);
            Calendar1.SelectedDate = inicioSemana(primeroMes);
            Calendar1.VisibleDate = Calendar1.SelectedDate.AddDays(15);
            DibujarMes();
        }

        private void setLabels()
        {
            DateTime fechaDesp = Calendar1.SelectedDate;
            for (int i = 0; i < 5; i++)
            {
                Label lunes = tablaPrincipal.FindControl("L" + i) as Label;
                Label martes = tablaPrincipal.FindControl("K" + i) as Label;
                Label miercoles = tablaPrincipal.FindControl("M" + i) as Label;
                Label jueves = tablaPrincipal.FindControl("J" + i) as Label;
                Label viernes = tablaPrincipal.FindControl("V" + i) as Label;
                Label sabado = tablaPrincipal.FindControl("S" + i) as Label;
                lunes.Text = fechaDesp.Day.ToString();
                fechaDesp = fechaDesp.AddDays(1);
                martes.Text = fechaDesp.Day.ToString();
                fechaDesp = fechaDesp.AddDays(1);
                miercoles.Text = fechaDesp.Day.ToString();
                fechaDesp = fechaDesp.AddDays(1);
                jueves.Text = fechaDesp.Day.ToString();
                fechaDesp = fechaDesp.AddDays(1);
                viernes.Text = fechaDesp.Day.ToString();
                fechaDesp = fechaDesp.AddDays(1);
                sabado.Text = fechaDesp.Day.ToString();
                fechaDesp = fechaDesp.AddDays(1);
                fechaDesp = fechaDesp.AddDays(1);
            }
        }

        protected void ClickRecuadro(Object sender, EventArgs e)
        {
            ImageButton cuadro = (ImageButton)sender;
            string tiempoDia = cuadro.ID.Substring(1, 1);
            IEnumerable<KeyValuePair<int, string>> reservacionesPeriodo = mapMTN.Where(x => x.Value == tiempoDia);
            int j = mapDias[(cuadro.ID.Substring(0, 1))];
            int k = Convert.ToInt32(cuadro.ID.Substring(2, 1));

            var comentarios = new RservacionModel();
            string despliegue = "";

            foreach (KeyValuePair<int, string> par in reservacionesPeriodo)
            {
                int i = par.Key;
                if (mapReservaciones[i, j, k] != null)
                {
                    if (mapReservaciones[i, j, k].Substring(mapReservaciones[i, j, k].Length - 1, 1) == "C")
                        despliegue += comentarios.ObtenerDetallesReservacion(Convert.ToInt32(mapReservaciones[i, j, k].Substring(0, mapReservaciones[i, j, k].Length - 1)), false);
                    else
                        despliegue += comentarios.ObtenerDetallesReservacionParticular(Convert.ToInt32(mapReservaciones[i, j, k].Substring(0, mapReservaciones[i, j, k].Length - 1)), false);
                    despliegue += "\\n";
                }
            }

            WebMsgBox.Show(despliegue, "Agenda: "+Calendar1.SelectedDate.AddDays((7*k) + j).ToShortDateString());
        }

        public IEnumerable<ImageButton> EnumerateRecursive(Control root)
        {
            Stack<Control> st = new Stack<Control>();
            st.Push(root);

            while (st.Count > 0)
            {
                var control = st.Pop();
                if (control is ImageButton)
                {
                    yield return (ImageButton)control;
                }

                foreach (Control child in control.Controls)
                {
                    st.Push(child);
                }
            }
        }

        private void LimpiarDespliegue()
        {
            foreach (ImageButton bot in EnumerateRecursive(tablaPrincipal))
            {
                bot.Visible = false;
            }
        }

        void AllControls(Control root, List<Control> accumulator)
        {
            accumulator.Add(root);
            foreach (Control ctrl in root.Controls)
            {
                AllControls(ctrl, accumulator);
            }
        }

        private void loopReservaciones(IEnumerable<ReservacionCurso> reservaciones)
        {
            foreach (ReservacionCurso reservacion in reservaciones)
            {
                reservacionPeriodica(reservacion.Reservacion, reservacion.id+"C");
            }
        }

        private void reservacionPeriodica(Reservacion res, string id)
        {
            var fechaDesp = Calendar1.SelectedDate;
            int i = mapHoras[res.HoraInicio.Split(':')[0]];
            int j;
            int k;
            string[] dias = res.Dias.Split('-');
            foreach (string dia in dias)
            {
                j = mapDias[dia];
                DateTime fechaAux = fechaDesp;
                for (k = 0; k < 5; k++)
                {
                    if (res.FechaInicio <= fechaAux.AddDays(j) &&
                    fechaAux.AddDays(j) <= res.FechaFinal)
                    {
                        string controlBot = dia + mapMTN[i] + k;
                        ImageButton cuadro = tablaPrincipal.FindControl(controlBot) as ImageButton;
                        cuadro.Visible = true;
                        mapReservaciones[i, j, k] = id;

                        if (i < 5 && i + res.Bloques > 4)
                        {
                            string controlBot2 = dia + "T" + k;
                            ImageButton cuadro2 = tablaPrincipal.FindControl(controlBot2) as ImageButton;
                            cuadro2.Visible = true;
                            mapReservaciones[5, j, k] = id;
                        }

                        if (i < 10 && i + res.Bloques > 9)
                        {
                            string controlBot3 = dia + "N" + k;
                            ImageButton cuadro3 = tablaPrincipal.FindControl(controlBot3) as ImageButton;
                            cuadro3.Visible = true;
                            mapReservaciones[10, j, k] = id;
                        }
                    }
                    fechaAux = fechaAux.AddDays(7);
                }
            }
        }

        private void loopReservacionesP(IEnumerable<ReservacionParticular> reservaciones)
        {
            var fechaDesp = Calendar1.SelectedDate;
            foreach (ReservacionParticular reservacion in reservaciones)
            {
                if (reservacion.Reservacion.FechaInicio == reservacion.Reservacion.FechaFinal)
                {
                    DateTime fechaRes = (DateTime)reservacion.Reservacion.FechaInicio;
                    if (fechaDesp <= fechaRes && fechaRes <= fechaDesp.AddDays(34))
                    {
                        int dias = fechaRes.Subtract(fechaDesp).Days;
                        int k = dias / 7;
                        int j = (int)fechaRes.DayOfWeek - 1;
                        int i = mapHoras[reservacion.Reservacion.HoraInicio.Split(':')[0]];
                        string dia = mapDias.First(x => x.Value == ((int)fechaRes.DayOfWeek-1)).Key;
                        string controlBot = dia + mapMTN[i] + k;
                        ImageButton cuadro = tablaPrincipal.FindControl(controlBot) as ImageButton;
                        cuadro.Visible = true;
                        mapReservaciones[i, j, k] = reservacion.id+"P";
                    }
                }
                else
                    reservacionPeriodica(reservacion.Reservacion, reservacion.id+"P");
            }
        }

        DateTime inicioSemana(DateTime fecha)
        {
            int diff = fecha.DayOfWeek - DayOfWeek.Monday;
            if (diff < 0)
            {
                diff += 7;
            }
            return fecha.AddDays(-1 * diff);
        }
    }
}